package util;

import java.io.File;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import javax.swing.DefaultListModel;

import model.OperacoesArquivos;

import org.encog.neural.data.NeuralDataSet;
import org.encog.neural.networks.BasicNetwork;
import org.encog.util.csv.CSVFormat;
import org.encog.util.simple.TrainingSetUtil;

import bean.DadosEntradaRNA;

public class Util {

	public static NeuralDataSet loadDataCSV(File fileCSV){
		NeuralDataSet trainingSet = TrainingSetUtil.loadCSVTOMemory(
				CSVFormat.ENGLISH, fileCSV.getAbsolutePath(),
				false, Constantes.INPUT_COUNT, Constantes.OUTPUT_COUNT);
		
		return trainingSet;
	}
	
	public static NeuralDataSet loadDataCSV(BasicNetwork network, File fileCSV){
		NeuralDataSet trainingSet = TrainingSetUtil.loadCSVTOMemory(
				CSVFormat.ENGLISH, fileCSV.getAbsolutePath(),
				false, network.getInputCount(), network.getOutputCount());
		
		return trainingSet;
	}
	
	//TODO implementar!!
	public static NeuralDataSet loadDataArray(BasicNetwork network, double arrayInput[], double arrayIdeal[]){
		NeuralDataSet trainingSet = null;
		
		return trainingSet;
	}
	
	public static char getPorte(int porteVeiculo){
		switch(porteVeiculo){
			case 1:
				return 'T';
			case 2:
				return 'P';
			case 3:
				return 'M';
			case 4:
				return 'C';
			case 5:
				return 'O';
			default:
				return 'I';
		}
	}
	
	public static int getPorte(char porteVeiculo){
		int ideal = -1;
		
		switch (porteVeiculo) {
			case 'T':
				ideal = 1;
				break;
			case 'P':
				ideal = 2;
				break;				
			case 'M':
				ideal = 3;
				break;				
			case 'G': //TODO DEVERA SER REMOVIDO, FUTURAMENTE
				ideal = 4;
				break;
			case 'C':
				ideal = 4;
				break;
			case 'O':
				ideal = 5;
				break;
			case 'X':
				ideal = 0;
				break;
			default:
				ideal = -1;
				break;
		}
		
		return ideal;
	}
	public static Calendar geraCalendar(String fluxo){
//		System.out.println(fluxo);
		try {
			int dayOfMonth = Integer.parseInt(fluxo.substring(12, 14));
			int month = Integer.parseInt(fluxo.substring(14, 16));
			int year = Integer.parseInt(fluxo.substring(16, 18));
			int hourOfDay = Integer.parseInt(fluxo.substring(18, 20));
			int minute = Integer.parseInt(fluxo.substring(20, 22));
			int second = Integer.parseInt(fluxo.substring(22, 24));
			
			Calendar calendar = new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
			
			return calendar;
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static int buscaBinaria(DefaultListModel lista, String item){
		try {
			int esq = 0;
			int dir = lista.size() - 1;
			int valorMeio;
 
			long valor = geraCalendar(item).getTimeInMillis();
			
			while (esq <= dir) {
			        valorMeio = esq + ((dir - esq) / 2);
			        
			        long current = geraCalendar(lista.get(valorMeio).toString()).getTimeInMillis();
			        
			        if (current < valor) {
			                esq = valorMeio + 1;
			        } else if(current > valor) {
			                dir = valorMeio - 1;
			        } else {
			                return valorMeio;
			        }
			}
		} catch (Exception e) {
//			e.printStackTrace();
			System.err.println("Invalid Fluxo");
			return -1;
		}
		
		return -1;
	}
	
	public static DadosEntradaRNA getDadosEntradaRNA(File file){
//		File file = new File(Constantes.DIRETORIO_PERFIL_CONSISTENCIA_COLETA, pathArquivo + Constantes.EXTENSAO_CSV);
		if(!file.exists()){
			System.err.println("Arquivo nao encontrado: " + file.getAbsolutePath());
			return null;
		}
		
		List<String> conteudo = OperacoesArquivos.lerTxt(file.getAbsolutePath());
				
		String linha = conteudo.get(0);
		String[] cortado = linha.split(",");
		
		DadosEntradaRNA input = new DadosEntradaRNA();
		input.setMa(Integer.parseInt(cortado[0]));
		input.setMb(Integer.parseInt(cortado[1]));
		input.setAa(Integer.parseInt(cortado[2]));
		input.setAb(Integer.parseInt(cortado[3]));
		input.setTa(Integer.parseInt(cortado[4]));
		input.setTb(Integer.parseInt(cortado[5]));
		input.setTd(Integer.parseInt(cortado[6]));
		input.setNa(Integer.parseInt(cortado[7]));
		input.setSaidaIdeal(Integer.parseInt(cortado[8]));
	
		return input;		
	}
	
	public static double outputAproximation(double value){
		double MOTO = 0.2;
		double VEICULO_PEQUENO = 0.4;
		double VEICULO_MEDIO = 0.6;
		double VEICULO_CAMINHAO = 0.8;
		double VEICULO_ONIBUS = 1.0;
//		String modelo;
		
		if(value < MOTO){
			value = MOTO;
//			modelo = "Moto";
		} else if( (value < VEICULO_PEQUENO) && 
				(Math.abs(value - MOTO) < Math.abs(value - VEICULO_PEQUENO)) ){
			value = MOTO;
//			modelo = "Moto";
		} else if( (value <= VEICULO_PEQUENO) && 
				(Math.abs(value - MOTO) > Math.abs(value - VEICULO_PEQUENO)) ){
			value = VEICULO_PEQUENO;
//			modelo = "P";
		} else if( (value < VEICULO_MEDIO) && 
				(Math.abs(value - VEICULO_PEQUENO) < Math.abs(value - VEICULO_MEDIO)) ){
			value = VEICULO_PEQUENO;
//			modelo = "P";
		} else if( (value <= VEICULO_MEDIO) && //
				(Math.abs(value - VEICULO_PEQUENO) > Math.abs(value - VEICULO_MEDIO)) ){
			value = VEICULO_MEDIO;
//			modelo = "M";
		} else if( (value < VEICULO_CAMINHAO) && 
				(Math.abs(value - VEICULO_MEDIO) < Math.abs(value - VEICULO_CAMINHAO)) ){
			value = VEICULO_MEDIO;
//			modelo = "M";
		} else if( (value <= VEICULO_CAMINHAO) && //
				(Math.abs(value - VEICULO_MEDIO) > Math.abs(value - VEICULO_CAMINHAO)) ){
			value = VEICULO_CAMINHAO;
//			modelo = "C";
		} else if( (value < VEICULO_ONIBUS) && 
				(Math.abs(value - VEICULO_CAMINHAO) < Math.abs(value - VEICULO_ONIBUS)) ){
			value = VEICULO_CAMINHAO;
//			modelo = "C";
		} else if( (value <= VEICULO_ONIBUS) && //
				(Math.abs(value - VEICULO_CAMINHAO) > Math.abs(value - VEICULO_ONIBUS)) ){
			value = VEICULO_ONIBUS;
//			modelo = "O";
		} else{
			value = VEICULO_ONIBUS;
//			modelo = "O";
		}
		
//		setClassificacao(modelo);
//		setValorClassificacao(value);
		
		return value;
	}
	
	public static double getTempoEmMilis(double tempoSeg) {
		return tempoSeg * 1000;
	}
	
	public static double getTempoEmSegundos(double tempoMilis) {
		return tempoMilis / 1000;
	}

	//transforma a velocidade de km/h para m/s
	public static double getVelocidadeEmMetrosPorSeg(double velocidadeKmPorHora){
		return velocidadeKmPorHora / 3.6;
	}
	
	//transforma a velocidade de m/s para km/h
	public static double getVelocidadeEmKmPorHora(double velocidadeMetrosPorSeg){
		return velocidadeMetrosPorSeg * 3.6;
	}
	
	/**
	 * Recebe como parametros
	 * @param tempo (em segundos)
	 * @param velocidade (m/s)	 * 
	 * @return comprimento (em metros)
	 */
	public static double getEspacoEmMetros(double tempoSeg, double velocidadeMetrosPorSeg){
		double comprimento = velocidadeMetrosPorSeg * tempoSeg;
		return comprimento;
	}
}